package testcase.command;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.NoSuchElementException;

import junit.framework.TestCase;

import org.junit.Test;

import satir.card.Choice;
import satir.card.Question;
import satir.command.AskQuestionCmd;
import satir.framework.test.PrivateAccessor;
import satir.player.Player;

public class In_Lv_2_AskQuestionCmd_1 extends TestCase{
	private AskQuestionCmd askQuestionCmd;
	private ArrayList<Choice> choices;
	private Question question; 
	private Player player;
	
	/**
	 * Sets up the test fixture. Called before every test case method.
	 */
	public void setUp() {

		// give choice
		choices = new ArrayList<Choice>();
		choices.add(new Choice(
				"Blame him/her and prohibit use the phone more than 5 mins.",
				1, new Hashtable<String, Integer>()));
		choices.add(new Choice("Talk with son/daughter and find the reason.",
				1, new Hashtable<String, Integer>()));
		choices.add(new Choice(
				"Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.",
				-1, new Hashtable<String, Integer>()));
		choices.add(new Choice("Ignore him/her.", -1,
				new Hashtable<String, Integer>()));

		// give a question
		String question1 = "Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?";
		player = new Player();
		question = new Question(question1, choices);

		// create questions array
		ArrayList<Question> questions = new ArrayList<Question>();
		questions.add(question);
		
		askQuestionCmd = new AskQuestionCmd(question, player);

	}
	/**
	 * Tears down the test fixture. Called after every test case method.
	 */
	public void tearDown() {
	}
	
	/*
	 * Test Case: 1
	 * Objective: Test Integration of AskQuestionCmd, Player, Question and Choice,  to award(increase) correct Self-Esteem value for Q1 C1 to player or not
	 */
	@Test
	public void testAnswerQuestion1WithChoice1(){
		final ByteArrayOutputStream systemOut = new ByteArrayOutputStream();
		PrintStream original = System.out;
		System.setOut(new PrintStream(systemOut)); // Start store the output here
		String input = "1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		System.setOut(original); // Store the output unit here
		
		String actualResult = systemOut.toString();
		String expectedResult = ("Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?\r\n" +
				"1. Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				"2. Talk with son/daughter and find the reason.\r\n" +
				"3. Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				"4. Ignore him/her.\r\n" +
				"Your Answer?\r\n" +
				"1 Awarded!!\r\n");

		assertEquals(actualResult,expectedResult);
		int actualSEValue = ((Integer) PrivateAccessor.getPrivateField(
				player, "selfEsteem")).intValue();
		assertEquals(6,actualSEValue);
	}
	/*
	 * Test Case: 2
	 * Objective: Test Integration of AskQuestionCmd, Player, Question and Choice,  to award(decrease) correct Self-Esteem value for Q1 C4 to player or not
	 */
	@Test
	public void testAnswerQuestion1WithChoice4(){
		final ByteArrayOutputStream systemOut = new ByteArrayOutputStream();
		PrintStream original = System.out;
		System.setOut(new PrintStream(systemOut)); // Start store the output here
		String input = "4";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		System.setOut(original); // Store the output unit here
		
		String actualResult = systemOut.toString();
		String expectedResult = ("Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?\r\n" +
				"1. Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				"2. Talk with son/daughter and find the reason.\r\n" +
				"3. Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				"4. Ignore him/her.\r\n" +
				"Your Answer?\r\n" +
				"-1 Awarded!!\r\n");

		assertEquals(actualResult,expectedResult);
		int actualSEValue = ((Integer) PrivateAccessor.getPrivateField(
				player, "selfEsteem")).intValue();
		assertEquals(4,actualSEValue);
	}
	/*
	 * Test Case: 3
	 * Objective: Test Integration of AskQuestionCmd, Player, Question and Choice,  to award correct Self-Esteem value for answering an out of range number then C1 to player or not
	 */
	@Test
	public void testAnswerQuestion1With5(){
		final ByteArrayOutputStream systemOut = new ByteArrayOutputStream();
		PrintStream original = System.out;
		System.setOut(new PrintStream(systemOut)); // Start store the output here
		String input = "5 1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		System.setOut(original); // Store the output unit here
		
		String actualResult = systemOut.toString();
		String expectedResult = ("Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?\r\n" +
				"1. Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				"2. Talk with son/daughter and find the reason.\r\n" +
				"3. Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				"4. Ignore him/her.\r\n" +
				"Your Answer?\r\n" +
				"Out of range!\r\n" +
				"Please indicate your selection:  [1] Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				", [2] Talk with son/daughter and find the reason.\r\n" +
				", [3] Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				", [4] Ignore him/her.\r\n\n" +
				"1 Awarded!!\r\n");

		assertEquals(actualResult,expectedResult);
		int actualSEValue = ((Integer) PrivateAccessor.getPrivateField(
				player, "selfEsteem")).intValue();
		assertEquals(6,actualSEValue);
	}
	/*
	 * Test Case: 4
	 * Objective: Test Integration of AskQuestionCmd, Player, Question and Choice,  to award correct Self-Esteem value for answering a letter then C1 to player or not
	 */
	@Test
	public void testAnswerQuestion1Witha(){
		final ByteArrayOutputStream systemOut = new ByteArrayOutputStream();
		PrintStream original = System.out;
		System.setOut(new PrintStream(systemOut)); // Start store the output here
		String input = "a 1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		System.setOut(original); // Store the output unit here
		
		String actualResult = systemOut.toString();
		String expectedResult = ("Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?\r\n" +
				"1. Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				"2. Talk with son/daughter and find the reason.\r\n" +
				"3. Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				"4. Ignore him/her.\r\n" +
				"Your Answer?\r\n" +
				"It is not a number.\r\n" +
				"Please indicate your selection:  [1] Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				", [2] Talk with son/daughter and find the reason.\r\n" +
				", [3] Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				", [4] Ignore him/her.\r\n\n" +
				"1 Awarded!!\r\n");

		assertEquals(actualResult,expectedResult);
		int actualSEValue = ((Integer) PrivateAccessor.getPrivateField(
				player, "selfEsteem")).intValue();
		assertEquals(6,actualSEValue);
	}
	/*
	 * Test Case: 5
	 * Objective: Test Integration of AskQuestionCmd, Player, Question and Choice,  to award correct Self-Esteem value for answering a symbol then C1 to player or not
	 */
	@Test
	public void testAnswerQuestion1WithSymbol(){
		final ByteArrayOutputStream systemOut = new ByteArrayOutputStream();
		PrintStream original = System.out;
		System.setOut(new PrintStream(systemOut)); // Start store the output here
		String input = "@ 1";
		System.setIn(new ByteArrayInputStream(input.getBytes()));
		try {
			askQuestionCmd.execute();
		} catch (NoSuchElementException e) {
		}
		System.setOut(original); // Store the output unit here
		
		String actualResult = systemOut.toString();
		String expectedResult = ("Mother notices her children talk with classmate at night about 30 mins or more. As Father, what is your decision?\r\n" +
				"1. Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				"2. Talk with son/daughter and find the reason.\r\n" +
				"3. Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				"4. Ignore him/her.\r\n" +
				"Your Answer?\r\n" +
				"It is not a number.\r\n" +
				"Please indicate your selection:  [1] Blame him/her and prohibit use the phone more than 5 mins.\r\n" +
				", [2] Talk with son/daughter and find the reason.\r\n" +
				", [3] Threaten son/daughter. If the situation still not change, you will modify the amount of pocket money.\r\n" +
				", [4] Ignore him/her.\r\n\n" +
				"1 Awarded!!\r\n");

		assertEquals(actualResult,expectedResult);
		int actualSEValue = ((Integer) PrivateAccessor.getPrivateField(
				player, "selfEsteem")).intValue();
		assertEquals(6,actualSEValue);
	}
}